package logic

import (
	"context"
	"errors"

	"wxapi/internal/services"
	"wxapi/internal/svc"
	"wxapi/internal/types"

	"github.com/shopspring/decimal"
	"github.com/zeromicro/go-zero/core/logx"
)

type PreCreateOrderLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewPreCreateOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PreCreateOrderLogic {
	return &PreCreateOrderLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *PreCreateOrderLogic) PreCreateOrder(req *types.PreCreateOrderReq) (resp *types.PreCreateOrderResp, err error) {
	userId, err := services.GetUserIdBySession(l.ctx, l.svcCtx, req.Session)
	if err != nil {
		return nil, err
	}

	user, err := services.GetUserById(l.ctx, l.svcCtx, userId)
	if err != nil {
		return nil, err
	}

	goods, err := services.GetCarGoods(l.ctx, l.svcCtx, user.ID)
	if err != nil {
		return nil, err
	}
	if len(goods) == 0 {
		return nil, errors.New("请先选择项目")
	}
	storeIdMap := make(map[int64]bool)
	for _, item := range goods {
		storeIdMap[item.StoreId] = true
	}
	if len(storeIdMap) > 1 {
		return nil, errors.New("只能选择一个商家下单")
	}

	store, err := services.GetStoreListById(l.ctx, l.svcCtx, goods[0].StoreId, req.Lat, req.Lon)
	if err != nil {
		return nil, err
	}
	if store == nil {
		return nil, errors.New("商家不存在")
	}
	storeInfo := types.OrderStoreInfo{
		ID:       store.ID,
		Name:     store.StoreName,
		Distance: services.GetDistance(store.StoreLocationLat, store.StoreLocationLon, req.Lat, req.Lon),
	}

	resp = &types.PreCreateOrderResp{
		Store: storeInfo,
	}

	items := make([]types.OrderItems, 0)
	for _, v := range goods {
		item := types.OrderItems{
			Doctor: types.OrderItemsDoctor{
				ID:     v.Doctor.ID,
				Name:   v.Doctor.DoctorName,
				Avatar: v.Doctor.DoctorAvatar,
				Title:  v.Doctor.Level.DoctorLevelName,
				Point:  v.Doctor.SellPoint.Point,
			},
			ID:       v.ID,
			Name:     v.Skill.Skill.SkillName,
			Duration: v.Skill.Duration,
			Price:    v.Skill.Price.InexactFloat64(),
			Date:     v.BeginTime.ToDateString(),
			Time:     v.BeginTime.Format("H:i"),
		}

		items = append(items, item)
	}

	resp.Items = items
	if store.OtherInfo != nil {
		resp.OrderDesc = store.OtherInfo.OrderDesc
	}
	if user.Member != nil && user.Member.Level != nil && user.Member.Level.Discount != nil {
		resp.MemberDiscount = types.OrderMemberDiscount{
			ID:       user.Member.Level.ID,
			Name:     user.Member.Level.LevelName,
			Discount: user.Member.Level.Discount.Discount.InexactFloat64(),
		}
	}

	payTypes, err := services.GetPayType(l.ctx, l.svcCtx)
	if err != nil {
		return nil, err
	}
	resp.PayType = make([]types.OrderPayType, 0)
	for _, v := range payTypes {
		item := types.OrderPayType{
			ID:     v.ID,
			Name:   v.Name,
			Avatar: v.Logo,
		}
		resp.PayType = append(resp.PayType, item)
	}

	amount := decimal.NewFromFloat(0.0)
	for _, v := range items {
		amount = amount.Add(decimal.NewFromFloat(v.Price))
	}
	resp.Amount = amount.InexactFloat64()
	if resp.MemberDiscount.ID != 0 {
		discount := decimal.NewFromFloat(resp.MemberDiscount.Discount).Div(decimal.NewFromFloat(10.0))
		amount = amount.Mul(discount)
	}
	resp.TotalAmount = amount.InexactFloat64()

	return
}
